package com.shycloud.mido.member.controller;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shycloud.mido.common.core.constant.SecurityConstants;
import com.shycloud.mido.common.core.util.R;
import com.shycloud.mido.common.pay.alipay.bean.AliReturnPayBean;
import com.shycloud.mido.common.security.util.SecurityUtils;
import com.shycloud.mido.common.util.NetworkUtil;
import com.shycloud.mido.common.util.SnowFlakeUtil;
import com.shycloud.mido.member.api.entity.MemberOrder;
import com.shycloud.mido.member.api.vo.PayHistoryVORep;
import com.shycloud.mido.member.constants.ShoppingStockConstants;
import com.shycloud.mido.member.mapper.MemberMoneyLogMapper;
import com.shycloud.mido.member.service.MemberOrderService;
import com.shycloud.mido.member.service.PayService;
import lombok.AllArgsConstructor;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.HashMap;
import java.util.Map;

/**
 * @author nianhua.jiang
 * @date 2020/7/8
 */
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/pay")
public class PayController {

	/** 支付模块 service */
	private final PayService payService;
	/** 会员订单模块 service */
	private final MemberOrderService memberOrderService;
	/** 会员充值记录 mapper */
	private final MemberMoneyLogMapper moneyMapper;

	@GetMapping("getOrderNo")
	public R getOrderNo() {
		Integer machineId = ShoppingStockConstants.getConsistentHash(NetworkUtil.getHostIp());
		long orderNo = new SnowFlakeUtil(1, machineId).nextId();
		return new R(String.valueOf(orderNo));
	}

	/**
	 * 微信支付
	 *
	 * @param request 微信支付请求体
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2020/7/8 13:32
	 */
	@PostMapping("/wxPay")
	public R<Object> wxPay(@RequestBody Map<String, Integer> map, HttpServletRequest request) {
		return new R<>(payService.wxPay(map, request));
	}

	/**
	 * 微信购买 vip
	 *
	 * @param map     业务参数
	 * @param request 响应参数
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2020/8/26 9:36
	 **/
	@PostMapping("/wxPayVip")
	public R<Object> wxPayVip(@RequestBody Map<String, Integer> map, HttpServletRequest request) {
		return new R<>(payService.wxPayVip(map, request));
	}

	/**
	 * 微信购买教辅权限
	 *
	 * @param map     业务参数
	 * @param request 响应参数
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2021/2/7 13:23
	 **/
	@PostMapping("/wxPayAssistPermission")
	public R wxPayAssistPermission(@RequestBody Map<String, Object> map,
			HttpServletRequest request) {
		return new R(payService.wxPayAssistPermission(map, request));
	}

	/**
	 * 微信购买在线课时
	 *
	 * @param map
	 * @param request
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2021/2/7 13:23
	 **/
	@PostMapping("/wxPayOnlineCourse")
	public R wxPayOnlineCourse(@RequestBody Map<String, Integer> map, HttpServletRequest request) {

		Integer orgId = map.get("orgId");

		Integer goodsId = map.get("goodsId");

		return new R(payService.wxPayOnlineCourse(orgId, goodsId, request));
	}

	/**
	 * 微信支付回调
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@PostMapping("/wxNotify")
	public void wxNotify(HttpServletRequest request, HttpServletResponse response) {
		payService.wxNotify(request, response);
	}

	/**
	 * 支付宝支付
	 *
	 * @return
	 */
	@PostMapping("/aliPay")
	public R aliPay(@RequestBody Map<String, Integer> map) {
		return new R(payService.aliPay(map));
	}

	/**
	 * 支付宝购买教辅权限
	 *
	 * @param map
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2021/2/9 09:39
	 **/
	@PostMapping("/aliPayAssistPermission")
	public R aliPayAssistPermission(@RequestBody Map<String, Object> map) {
		return new R(payService.aliPayAssistPermission(map));
	}

	/**
	 * 支付宝购买在线课时包
	 *
	 * @param map
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2021/2/9 09:39
	 **/
	@PostMapping("/aliPayOnlineCourse")
	public R aliPayOnlineCourse(@RequestBody Map<String, Integer> map) {
		return new R(payService.aliPayOnlineCourse(map));
	}

	@PostMapping("/aliPayHardwareDeposit")
	public R aliPayHardwareDeposit(@RequestBody Map<String, Object> map) {
		return new R(payService.aliPayHardwareDeposit(map));
	}

	/**
	 * 支付宝购买 VIP
	 *
	 * @return
	 */
	@PostMapping("/aliPayVip")
	public R aliPayVip(@RequestBody Map<String, Integer> map) {
		return new R(payService.aliPayVip(map));
	}

	/**
	 * 支付宝支付回调
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@PostMapping("/aliNotify")
	public String aliNotify(HttpServletRequest request, AliReturnPayBean returnPay,
			HttpServletResponse response) {
		return payService.aliNotify(request, returnPay, response);
	}

	/**
	 * 获取支付结果
	 *
	 * @param orderNo
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2020/8/7 10:59
	 */
	@GetMapping("getPayResult")
	public R getPayResult(String orderNo) {
		return new R(
				memberOrderService.getOne(new QueryWrapper<MemberOrder>().eq("order_no", orderNo)));
	}

	/**
	 * 校验ios凭证
	 *
	 * @param
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2020/8/10 10:18
	 */
	@PostMapping("getIosPayResult")
	public R getIosPayResult(@RequestBody Map<String, String> map) {

		//价格ID
		String productId = map.get("productId");
		//苹果内购交易ID
		String transactionId = map.get("transactionId");
		//base64校验体
		String payload = map.get("transactionReceipt");
		//订单ID
		String orderId = map.get("orderId");
		return new R(payService.getIosPayResult(orderId, productId, transactionId, payload));

	}

	/**
	 * 购买单本曲集
	 *
	 * @param collectionId
	 * @return com.shycloud.mido.common.core.util.R
	 * @throws Exception
	 * @author nianhua.jiang
	 * @date 2020/8/10 9:51
	 */
	@GetMapping("payCollection")
	public R payCollection(Integer collectionId) {
		return new R(payService.payCollection(collectionId));
	}

	@PostMapping("payVipForIos")
	public R payVipForIos(@RequestBody Map<String, String> map) {

		//会员包ID
		String productId = map.get("productId");
		//苹果内购交易ID
		String transactionId = map.get("transactionId");
		//base64校验体
		String payload = map.get("transactionReceipt");
		//订单ID
		String orderId = map.get("orderId");
		//续订ID
		String originalTransactionId = map.get("originalTransactionId");

		payService.addIosOrderLog(orderId, productId, transactionId, payload, SecurityUtils.getMember().getId());

		return new R(payService.payVipForIos(orderId, productId, transactionId, payload, originalTransactionId));
	}

	/**
	 * IOS 教辅权限支付
	 *
	 * @param map
	 * @return com.shycloud.mido.common.core.util.R
	 * @throws Exception
	 * @author nianhua.jiang
	 * @date 2021/2/7 14:04
	 **/
	@PostMapping("payAssistForIos")
	public R payAssistForIos(@RequestBody Map<String, String> map) throws Exception {

		//会员包ID
		String productId = map.get("productId");
		//苹果内购交易ID
		String transactionId = map.get("transactionId");
		//base64校验体
		String payload = map.get("transactionReceipt");
		//教师ID
		String teacherId = map.get("teacherId");
		//学生ID
		String studentId = map.get("studentId");
		//订单ID
		String orderId = map.get("orderId");
		return new R(payService.payAssistForIos(orderId, productId, transactionId, payload, teacherId, studentId));
	}

	/**
	 * IOS 课时包购买
	 *
	 * @param map
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2021/2/7 14:04
	 **/
	@PostMapping("iosPayOnlineCourse")
	public R iosPayOnlineCourse(@RequestBody Map<String, Object> map) {

		//会员包ID
		String productId = (String) map.get("productId");
		//苹果内购交易ID
		String transactionId = (String) map.get("transactionId");
		//base64校验体
		String payload = (String) map.get("transactionReceipt");
		//机构ID
		Integer orgId = (Integer) map.get("orgId");
		//订单ID
		String orderId = (String) map.get("orderId");

		return new R(payService.payOnlineCourseForIos(orderId, productId, transactionId, payload, orgId));
	}


	/**
	 * H5页面支付套餐
	 *
	 * @param map
	 * @return com.shycloud.mido.common.core.util.R
	 * @author nianhua.jiang
	 * @date 2020/11/18 10:14
	 **/
	@PostMapping("payComboH5")
	public R payComboH5(@RequestBody Map<String, Object> map) {
		return new R(payService.payComboH5(map));
	}

	/**
	 * H5页面支付回调
	 *
	 * @param request
	 * @param returnPay 支付宝返回数据实体
	 * @param response
	 * @author nianhua.jiang
	 * @date 2020/11/18 10:14
	 **/
	@PostMapping("payComboH5Notify")
	public void payComboH5Notify(HttpServletRequest request, AliReturnPayBean returnPay,
			HttpServletResponse response) {
		payService.payComboH5Notify(request, returnPay, response);
	}

	/**
	 * 获取 H5 套餐支付结果
	 *
	 * @param orderNo
	 * @return
	 * @author nianhua.jiang
	 * @date 2020/11/18 14:27
	 **/
	@GetMapping("getComboH5Result")
	public R getComboH5Result(String orderNo) {
		return new R(payService.getComboH5Result(orderNo));
	}

	/**********************************************下方是后台接口************************************************/

	/**
	 * 后台管理 - 用户订单界面 - 获取用户订单列表
	 *
	 * @param page      分页参数
	 * @param username  用户账号
	 * @param payMethod 1.支付宝  2.微信 3.ios内购
	 * @return {@link R}
	 * @author nianhua.jiang
	 * @date 2021/5/24 13:19
	 **/
	@GetMapping("/getPayHistoryList")
	public R<IPage<PayHistoryVORep>> getPayHistoryList(Page page, String username, String payMethod,
			String orderType, String status, String startTime, String endTime) {
		return new R<>(memberOrderService.getPayHistoryList(page, username, payMethod, orderType, status, startTime, endTime));
	}

	/**
	 * 后台管理 - 用户订单界面 - 获取用户押金订单接口
	 *
	 * @param page      分页参数
	 * @param payMethod 1.支付宝  2.微信 3.ios内购
	 * @return {@link R}
	 * @author nianhua.jiang
	 * @date 2021/5/24 13:19
	 **/
	@GetMapping("/getPayHistoryListDeposit")
	public R<IPage<PayHistoryVORep>> getPayHistoryListDeposit(String orderNo, String fuwuOrderNo, Page page, String payMethod,
			String orderType, String status) {
		return new R<>(memberOrderService.getPayHistoryListDeposit(page, orderNo, fuwuOrderNo, payMethod, orderType, status));
	}

	@GetMapping("/getPayStatistics")
	public R getPayStatistics() {
		String moneyTotal = "0";
		String memberTotal = "0";
		String depositOrderTotal = "0";
		moneyTotal = moneyMapper.moneyTotal();
		memberTotal = moneyMapper.memberTotal();
		//查询押金订单总金额
		depositOrderTotal = moneyMapper.depositOrderTotal();
		Map<String, String> map = new HashMap<>();
		map.put("moneyTotal", moneyTotal);
		map.put("memberTotal", memberTotal);
		map.put("depositOrderTotal", depositOrderTotal);
		return new R<>(map);
	}

	@GetMapping("/getLiveRoomOrder")
	public R getLiveRoomOrder(Page page, String phone, String name, String date) {
		QueryWrapper<MemberOrder> queryWrapper = new QueryWrapper<MemberOrder>();
		queryWrapper.and(Wrapper -> Wrapper.eq("order_type", 5).or().eq("order_type", 6));
		//queryWrapper.eq("order_type", 5);
		// queryWrapper.eq("order_type", 6);
		if (StringUtils.isNotBlank(phone)) {
			queryWrapper.like("member_id", phone);
		}
		if (StringUtils.isNotBlank(name)) {
			queryWrapper.like("remark", name);
		}
		if (StringUtils.isNotBlank(date)) {
			queryWrapper.apply("date_format(create_time,'%Y-%m-%d') = date_format('" + date
					+ "','%Y-%m-%d')");
			//queryWrapper.eq("create_time", date);
		}
		return new R<>(memberOrderService.page(page, queryWrapper));
	}

	@PostMapping("/wxMiniPay")
	public R wxMiniPay(@RequestBody Map<String, String> map, HttpServletRequest request) {
		return new R<>(payService.wxMiniPay(map, request));
	}

	@GetMapping("/wxMiniPayResult")
	public R wxMiniPayResult(String orderNo) {
		if ("1".equals(
				memberOrderService.getOne(new QueryWrapper<MemberOrder>().eq("order_no", orderNo))
						.getStatus())) {
			return new R(true);
		} else {
			return new R(false);
		}
	}

	/**
	 * 微信支付硬件设备押金
	 *
	 * @param map     参数信息
	 * @param request 请求体
	 * @return {@link R}
	 * @author nianhua.jiang
	 * @date 2021/10/22 14:09
	 */
	@PostMapping("wxPayHardwareDeposit")
	public R wxPayHardwareDeposit(@RequestBody Map<String, Object> map,
			HttpServletRequest request) {
		return new R(payService.wxPayHardwareDeposit(map, request));
	}

	@GetMapping("getHardwareDepositResult")
	public R getPayHardwareDepositResult(String orderNo) {
		return new R(payService.getPayHardwareDepositResult(orderNo));
	}

	@GetMapping("/getWxOpenId")
	public R getWxOpenId(String code) {

		String url = String
				.format(SecurityConstants.WX_AUTHORIZATION_CODE_MINI_URL, "wx501bca0b53e0b135", "9a33cc36369458fba574ce4e9215b716",
						code);
		String result = HttpUtil.get(url);
		System.out.println("=========================微信响应报文:{" + result + "}");
		Object obj = JSONUtil.parseObj(result).get("openid");
		if (obj == null) {
			return null;
		}
		//保存token信息
		return new R(obj.toString());
	}

	@PostMapping("iosNotify")
	public void iosNotify(@RequestBody Map<String, String> reqMap, HttpServletRequest request, HttpServletResponse response) {
		String signedPayload = reqMap.get("signedPayload");
		//解析数据
		log.info("IOS续费回调 ========> " + signedPayload);
		payService.iosNotify(signedPayload);
	}

	@PostMapping("agreementSignNotify")
	public void aliAgreementSignNotify(HttpServletRequest request, AliReturnPayBean returnPay,
			HttpServletResponse response) {
		payService.aliAgreementSignNotify(request, returnPay, response);
	}

	/**
	 * 支付宝主动扣款
	 *
	 * @return {@link R}
	 * @author nianhua.jiang
	 * @date 2021/11/25 10:18
	 */
	@GetMapping("batchAliTradePay")
	public R batchAliTradePay() {
		return new R(payService.batchAliTradePay());
	}

}
